﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevComponents.Editors;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Metro;
using ProductManagement.Ultilities;

namespace ProductManagement.Forms
{
    /// <summary>
    /// Form chính
    /// </summary>
    public partial class MainForm : MetroForm
    {
        #region Các trường

        /// <summary>
        /// Đối tượng liên kết dữ liệu LinQ to SQL, để thao tác với cơ sở dữ liệu
        /// </summary>
        private ProductManagementClassesDataContext db = new ProductManagementClassesDataContext();
        /// <summary>
        /// Đối tượng kiểm tra tính hợp lệ của dữ liệu nhập vào
        /// </summary>
        private Validator validator = new Validator();

        #endregion

        #region Hàm khởi tạo

        public MainForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Các phương thức khác

        /// <summary>
        /// Hiển thị thông tin nhập / xuất sản phẩm trong dgvImportExport sau khi nhập / xuất một sản phẩm
        /// </summary>
        /// <param name="reportID">id của báo cáo</param>
        /// <param name="mainForm">đối tượng MainForm đang chạy</param>
        public void DisplayExportImportInfo(int reportID)
        {
            dgvImportExport.DataSource = db.sp_GetReportDetails(reportID);
            dgvImportExport.Columns[2].Visible = false;
            dgvImportExport.Columns[3].Visible = false;
            dgvImportExport.Columns[1].Visible = false;
            int count = (int)db.sp_GetReportDetailsCount(reportID).SingleOrDefault().dem;
            for (int i = 0; i < count; i++)
            {
                dgvImportExport[0, i].Value = i + 1;
            }
            decimal sum = (decimal)db.sp_GetReportSumPrice(reportID).SingleOrDefault().tong;
            db.sp_UpdateReportSumPrice(reportID, sum);
            lblSumPrice.Text = "<b>Tổng giá trị nhập / xuất: " + sum.ToString("0,0") + " (VNĐ)</b>";
        }

        /// <summary>
        /// Hiển thị thông tin toàn bộ sản phẩm sau khi sửa thông tin một sản phẩm trên dgvGeneral
        /// </summary>
        /// <param name="mainForm">đối tượng MainForm đang chạy</param>
        public void DisplayGeneralInfoAfterEdit()
        {
            dgvGeneral.DataSource = db.sp_GetAllProducts();
        }

        /// <summary>
        /// Reset bảng thông tin nhập xuất sản phẩm
        /// </summary>
        private void ResetImportExportDgv()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("name");
            dt.Columns.Add("price");
            dt.Columns.Add("quantity");
            dgvImportExport.DataSource = dt;
            lblSumPrice.Text = "<b>Tổng giá trị nhập / xuất :</b>";
        }

        /// <summary>
        /// Làm mới bảng dữ liệu báo cáo
        /// </summary>
        /// <param name="mainForm">Form chính</param>
        public void ResetDgvAllReport()
        {
            dgvAllReport.DataSource = db.sp_GetAllReports();
        }

        #endregion

        #region Xử lý sự kiện

        #region Sự kiện trong tab Tổng quan

        /// <summary>
        /// Sự kiện chọn tab Tổng quan
        /// </summary>
        private void stiGeneral_Click(object sender, EventArgs e)
        {
            // Load dữ liệu về thông tin toàn bộ sản phẩm lên datagridview
            var products = db.sp_GetAllProducts();
            dgvGeneral.DataSource = products;
        }

        /// <summary>
        /// Sự kiện giá trị của combox kiểu tìm kiếm bị thay đổi
        /// </summary>
        private void cbxSearchType_SelectionChangeCommitted(object sender, EventArgs e)
        {
            // Nếu trong combobox đã có các items thì xóa các items đó đi
            int count = cbxSearchRange.Items.Count;
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                    ((ComboItem)cbxSearchRange.Items[i]).Dispose();
                cbxSearchRange.Items.Clear();
            }
            // Nếu người dùng chọn tìm kiếm theo Tên sản phẩm hoặc theo Năm sản xuất
            // thì hiển thị textbox để người dùng nhập giá trị
            if (cbxSearchType.SelectedItem == ciSearchName || cbxSearchType.SelectedItem == ciSearchYear)
            {
                cbxSearchRange.Visible = false;
                txtSearchValue.Visible = true;
                txtSearchValue.ResetText();
            }
            // Nếu người dùng chọn tìm kiếm theo giá thành
            // thì hiển thị combobox, tạo các comboitem thể hiện các khoảng giá
            if (cbxSearchType.SelectedItem == ciSearchPrice)
            {
                txtSearchValue.Visible = false;
                cbxSearchRange.Visible = true;
                ComboItem[] items = new ComboItem[6];
                items[0] = new ComboItem("0 - 100000");
                items[1] = new ComboItem("100000 - 500000");
                items[2] = new ComboItem("500000 - 1000000");
                items[3] = new ComboItem("1000000 - 5000000");
                items[4] = new ComboItem("5000000 - 10000000");
                items[5] = new ComboItem("10000000 - up");
                for (int i = 0; i < 6; i++)
                {
                    cbxSearchRange.Items.Add(items[i]);
                }
            }
            // Nếu người dùng chọn tìm kiếm theo số lượng
            // thì hiển thị combobox, tạo các comboitem thể hiện các khoảng số lượng
            if (cbxSearchType.SelectedItem == ciSearchQuantity)
            {
                txtSearchValue.Visible = false;
                cbxSearchRange.Visible = true;
                ComboItem[] items = new ComboItem[6];
                items[0] = new ComboItem("0 - 100");
                items[1] = new ComboItem("100 - 500");
                items[2] = new ComboItem("500 - 1000");
                items[3] = new ComboItem("1000 - 5000");
                items[4] = new ComboItem("5000 - 10000");
                items[5] = new ComboItem("10000 - up");
                for (int i = 0; i < 6; i++)
                {
                    cbxSearchRange.Items.Add(items[i]);
                }
            }
            // Nếu người dùng chọn tìm kiếm theo trạng thái
            // thì hiển thị combobox, tạo các comboitem thể hiện hai trạng thái: Còn hàng và Hết hàng
            if (cbxSearchType.SelectedItem == ciSearchState)
            {
                txtSearchValue.Visible = false;
                cbxSearchRange.Visible = true;
                ComboItem[] items = new ComboItem[2];
                items[0] = new ComboItem("Còn hàng");
                items[1] = new ComboItem("Hết hàng");
                for (int i = 0; i < 2; i++)
                {
                    cbxSearchRange.Items.Add(items[i]);
                }
            }
        }

        /// <summary>
        /// Sự kiện người dùng nhấn nút Tìm kiếm (thực hiện tìm kiếm theo lựa chọn và hiển thị kết quả trên datagridview)
        /// </summary>
        private void btnSearch_Click(object sender, EventArgs e)
        {
            // Nếu người dùng chọn tìm kiếm theo tên
            if (cbxSearchType.SelectedItem == ciSearchName)
            {
                // Gọi stored procedure tìm kiếm theo tên và load dữ liệu kết quả tìm kiếm cho datagridview
                var searchResult = db.sp_SearchByName(txtSearchValue.Text);
                dgvGeneral.DataSource = searchResult;
            }
            // Nếu người dùng chọn tìm kiếm theo giá
            if (cbxSearchType.SelectedItem == ciSearchPrice)
            {
                // Lấy giá trị nhỏ nhất và lớn nhất của khoảng giá
                string tempText = cbxSearchRange.Text.Replace(" ", "");
                string[] rangeValues = tempText.Split('-');
                decimal min = Decimal.Parse(rangeValues[0]);
                try
                {
                    // Nếu khoảng giá không chứa từ "up"
                    decimal max = Decimal.Parse(rangeValues[1]);
                    // Gọi stored procedure tìm kiếm theo khoảng giá kiểu 1 và load dữ liệu kết quả tìm kiếm cho datagridview
                    var searchResult = db.sp_SearchByPrice(min, max, 1);
                    dgvGeneral.DataSource = searchResult;
                }
                catch (FormatException)
                {
                    // Nếu khoảng giá chứa từ "up"
                    // Gọi stored procedure tìm kiếm theo khoảng giá kiểu 2 và load dữ liệu kết quả tìm kiếm cho datagridview
                    var searchResult = db.sp_SearchByPrice(min, 0, 2);
                    dgvGeneral.DataSource = searchResult;
                }
            }
            // Nếu người dùng chọn tìm kiếm theo khoảng số lượng
            if (cbxSearchType.SelectedItem == ciSearchQuantity)
            {
                // Lấy giá trị nhỏ nhất và lớn nhất của khoảng số lượng
                string tempText = cbxSearchRange.Text.Replace(" ", "");
                string[] rangeValues = tempText.Split('-');
                int min = Int32.Parse(rangeValues[0]);
                try
                {
                    // Nếu khoảng số lượng không chứa từ "up"
                    int max = Int32.Parse(rangeValues[1]);
                    // Gọi stored procedure tìm kiếm theo khoảng số lượng kiểu 1 và load dữ liệu kết quả tìm kiếm cho datagridview
                    var searchResult = db.sp_SearchByQuantity(min, max, 1);
                    dgvGeneral.DataSource = searchResult;
                }
                catch (FormatException)
                {
                    // Nếu khoảng số lượng chứa từ "up"
                    // Gọi stored procedure tìm kiếm theo khoảng số lượng kiểu 2 và load dữ liệu kết quả tìm kiếm cho datagridview
                    var searchResult = db.sp_SearchByQuantity(min, 0, 2);
                    dgvGeneral.DataSource = searchResult;
                }
            }
            // Nếu người dùng chọn tìm kiếm theo năm
            if (cbxSearchType.SelectedItem == ciSearchYear)
            {
                try
                {
                    // Kiểm tra tính hợp lệ của năm được nhập vào
                    int year = Int32.Parse(txtSearchValue.Text);
                    if (year > DateTime.Now.Year)
                        errorProvider1.SetError(txtSearchValue, "Năm sản xuất không được lớn hơn năm hiện tại!");
                    else if (year < 0)
                        errorProvider1.SetError(txtSearchValue, "Năm sản xuất phải lớn hơn 0!");
                    else
                    {
                        // Gọi stored procedure tìm kiếm theo năm và load dữ liệu kết quản lên datagridview
                        var searchResult = db.sp_SearchByYear(year);
                        dgvGeneral.DataSource = searchResult;
                    }
                }
                catch (FormatException)
                {
                    errorProvider1.SetError(txtSearchValue, "Năm sản xuất phải là số nguyên!");
                }
            }
            // Nếu người dùng chọn tìm kiếm theo trạng thái
            if (cbxSearchType.SelectedItem == ciSearchState)
            {
                // Gọi stored procedure tìm kiếm theo trạng thái và load dữ liệu kết quản lên datagridview
                var searchResult = db.sp_SearchByState(cbxSearchRange.Text);
                dgvGeneral.DataSource = searchResult;
            }
        }

        /// <summary>
        /// Sự kiện nhấn nút Quay lại 
        /// Reset các trường text và load dữ liệu thông tin toàn bộ sản phẩm vào datagridview
        /// </summary>
        private void btnBackToGeneral_Click(object sender, EventArgs e)
        {
            cbxSearchRange.ResetText();
            cbxSearchType.ResetText();
            txtSearchValue.ResetText();
            var products = db.sp_GetAllProducts();
            dgvGeneral.DataSource = products;
        }

        /// <summary>
        /// Sự kiện nhấn nút Xóa trong tab Tổng quan
        /// </summary>
        private void btnDeleteProduct_Click(object sender, EventArgs e)
        {
            try
            {
                // Lấy chỉ số hàng của ô đang được chọn
                int rowIndex = dgvGeneral.SelectedCells[0].RowIndex;
                if (rowIndex >= 0)
                {
                    int productID = (int)dgvGeneral[0, rowIndex].Value;
                    // Hiển thị hộp thoại lựa chọn, lưu lựa chọn của người dùng vào biến dr
                    DialogResult dr = MessageBoxEx.Show("Bạn có muốn xóa sản phẩm này?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    // Nếu người dùng chọn Yes
                    if (dr == DialogResult.Yes)
                    {
                        // Xóa sản phẩm khỏi cơ sở dữ liệu
                        db.sp_DeleteProduct(productID);
                        MessageBoxEx.Show("Xóa sản phẩm thành công", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    db.SubmitChanges();
                    // Load lại dữ liệu cho datagridview
                    dgvGeneral.DataSource = db.sp_GetAllProducts();
                }
            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString());
            }
        }

        /// <summary>
        /// Sự kiện nhấn nút Sửa trong tab Tổng quan (hiển thị form sửa thông tin sản phẩm)
        /// </summary>
        private void btnEditProduct_Click(object sender, EventArgs e)
        {
            try
            {
                // Lấy chỉ số hàng của ô đang được chọn
                int rowIndex = dgvGeneral.SelectedCells[0].RowIndex;
                if (rowIndex >= 0)
                {
                    // Lấy ID sản phẩm từ datagridview
                    int productID = (int)dgvGeneral[0, rowIndex].Value;
                    // Tạo mới & hiển thị form sửa thông tin sản phẩm
                    EditForm editForm = new EditForm(productID, this);
                    editForm.ShowDialog();
                }
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString());
            }
        }

        /// <summary>
        /// Sự kiện chọn Sửa trong menu chuột phải trong tab Tổng quan (giống sự kiện nhấn nút Sửa)
        /// </summary>
        private void tsmiEditProduct_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvGeneral.SelectedCells[0].RowIndex;
                if (rowIndex >= 0)
                {
                    int productID = (int)dgvGeneral[0, rowIndex].Value;
                    EditForm editForm = new EditForm(productID, this);
                    editForm.Show();
                }
            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString());
            }
        }

        /// <summary>
        /// Sự kiện chọn Xóa trong menu chuột phải trong tab Tổng quan (giống sự kiện nhấn nút Xóa)
        /// </summary>
        private void tsmiDeleteProduct_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvGeneral.SelectedCells[0].RowIndex;
                if (rowIndex >= 0)
                {
                    int productID = (int)dgvGeneral[0, rowIndex].Value;
                    DialogResult dr = MessageBoxEx.Show("Bạn có muốn xóa sản phẩm này?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (dr == DialogResult.Yes)
                    {
                        db.sp_DeleteProduct(productID);
                        MessageBoxEx.Show("Xóa sản phẩm thành công", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    db.SubmitChanges();
                    dgvGeneral.DataSource = db.sp_GetAllProducts();
                }
            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString());
            }
        }

        #endregion

        #region Sự kiện trong tab Nhập / Xuất sản phẩm

        /// <summary>
        /// Sự kiện chọn tab Nhập / Xuất sản phẩm
        /// </summary>
        private void stiImportExport_Click(object sender, EventArgs e)
        {
            ResetImportExportDgv();
        }

        /// <summary>
        /// Sự kiện nhấn nút Nhập trong tab Nhập / Xuất sản phẩm
        /// </summary>
        private void btnImport_Click(object sender, EventArgs e)
        {
            ResetImportExportDgv();
            DateTime date = DateTime.Now;
            // Tạo báo cáo mới trong cơ sở dữ liệu, công việc là "Nhập hàng", thời gian lập báo cáo là date
            db.sp_InsertReport("Nhập hàng", date);
            // Lấy ID của báo cáo
            int reportID = db.sp_GetReportID("Nhập hàng", date).SingleOrDefault().id;
            // Tạo và hiển thị form nhập sản phẩm
            ImportForm importForm = new ImportForm(reportID, this);
            importForm.ShowDialog();
        }

        /// <summary>
        /// Sự kiện nhấn nút Xuất trong tab Nhập / Xuất sản phẩm
        /// </summary>
        private void btnExport_Click(object sender, EventArgs e)
        {
            ResetImportExportDgv();
            DateTime date = DateTime.Now;
            // Tạo báo cáo mới trong cơ sở dữ liệu, công việc là "Xuất hàng", thời gian lập báo cáo là date
            db.sp_InsertReport("Xuất hàng", date);
            // Lấy ID của báo cáo
            int reportID = db.sp_GetReportID("Xuất hàng", date).SingleOrDefault().id;
            // Tạo và hiển thị form xuất sản phẩm
            ExportForm exportForm = new ExportForm(reportID, this);
            exportForm.ShowDialog();
        }

        /// <summary>
        /// Sự kiện chọn Xóa trong menu chuột phải trong tab Nhập / Xuất sản phẩm
        /// </summary>
        private void tsmiDeleteDetail_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvImportExport.SelectedCells[0].RowIndex;
                int reportID = (int)dgvImportExport[3, rowIndex].Value;
                int reportDetailID = (int)dgvImportExport[1, rowIndex].Value;
                int productID = (int)dgvImportExport[2, rowIndex].Value;
                int reportDetailQuantity = (int)dgvImportExport[6, rowIndex].Value;
                int oldQuantity = db.sp_GetProductQuantity(productID).SingleOrDefault().quantity + reportDetailQuantity;
                string task = db.sp_GetReportTask(reportID).SingleOrDefault().task;
                db.sp_DeleteReportDetail(reportDetailID);
                if (task.ToLower().Contains("nhập"))
                    db.sp_DeleteProduct(productID);
                else
                    db.sp_UpdateProductQuantity(oldQuantity, productID);
                int countReportDetail = (int)db.sp_GetReportDetailsCount(reportID).SingleOrDefault().dem;
                if (countReportDetail == 0)
                {
                    db.sp_DeleteReport(reportID);
                    ResetImportExportDgv();
                }
                else
                    DisplayExportImportInfo(reportID);
                db.SubmitChanges();
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString(), "Ngoại lệ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region Sự kiện trong tab Lịch sử nhập xuất

        /// <summary>
        /// Sự kiện chọn tab Lịch sử nhập xuất
        /// </summary>
        private void stiHistory_Click(object sender, EventArgs e)
        {
            var reports = db.sp_GetAllReports();
            dgvAllReport.DataSource = reports;
        }

        /// <summary>
        /// Sự kiện nhấn nút Xóa trong tab Lịch sử nhập xuất
        /// </summary>
        private void btnDeleteReport_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvAllReport.SelectedCells[0].RowIndex;
                int reportID = (int)dgvAllReport[0, rowIndex].Value;
                DialogResult dr = MessageBoxEx.Show("Bạn có muốn xóa báo cáo đã chọn?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    db.sp_DeleteReport(reportID);
                    MessageBoxEx.Show("Xóa báo cáo thành công!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                dgvAllReport.DataSource = db.sp_GetAllReports();
                db.SubmitChanges();
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString(), "Ngoại lệ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Sự kiện chọn Xóa trong menu chuột phải trong tab Lịch sử nhập xuất
        /// </summary>
        private void tsmiDeleteReport_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvAllReport.SelectedCells[0].RowIndex;
                int reportID = (int)dgvAllReport[0, rowIndex].Value;
                DialogResult dr = MessageBoxEx.Show("Bạn có muốn xóa báo cáo đã chọn?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    db.sp_DeleteReport(reportID);
                    MessageBoxEx.Show("Xóa báo cáo thành công!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                dgvAllReport.DataSource = db.sp_GetAllReports();
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString(), "Ngoại lệ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Sự kiện nhấn nút Xem chi tiết trong tab Lịch sử nhập xuất
        /// </summary>
        private void btnReportDetail_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvAllReport.SelectedCells[0].RowIndex;
                int reportID = (int)dgvAllReport[0, rowIndex].Value;
                string reportTask = dgvAllReport[1, rowIndex].Value.ToString();
                ReportForm reportForm = new ReportForm(reportID, reportTask, this);
                reportForm.ShowDialog();
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString(), "Ngoại lệ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Sự kiện chọn Xem chi tiết trong meu chuột phải trong tab Lịch sử nhập xuất
        /// </summary>
        private void tsmiReportDetail_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dgvAllReport.SelectedCells[0].RowIndex;
                int reportID = (int)dgvAllReport[0, rowIndex].Value;
                string reportTask = dgvAllReport[1, rowIndex].Value.ToString();
                ReportForm reportForm = new ReportForm(reportID, reportTask, this);
                reportForm.ShowDialog();
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.ToString(), "Ngoại lệ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        /// <summary>
        /// Sự kiện load form
        /// </summary>
        private void MainForm_Load(object sender, EventArgs e)
        {
            // Load dữ liệu thông tin tất cả sản phẩm cho datagridview 
            dgvGeneral.DataSource = db.sp_GetAllProducts();
        }

        #endregion
    }
}
